package btp.Time;

import btp.Calendars.GregorianCalendar;
import btp.Calendars.JulianCalendar;
import btp.Calendars.JulianDay;


public class DynamicTime extends Time{

	public DynamicTime(int hours, int minutes, double seconds) {
		super(hours, minutes, seconds);
	}


	public DynamicTime(int hours, int minutes, double seconds, long rd) {
		super(hours, minutes, seconds, rd);
	}


	private static double getDeltaT(Time t){
		GregorianCalendar g = GregorianCalendar.getDayFromRD(t.rd);
		int year = g.getYear();
		double deltaT=0;
		if(year>=-390 && year<948){
			double T=(year-948)/100.0;
			deltaT = 1830+405*T+46.5*T*T;
		}
		else if(year>=948 && year<1600){
			double T = (year-1850)/100.0;
			deltaT = 22.5*T*T;
		}
		else if(year>=1800 && year<1899){
			double theta = (t.rd-JulianCalendar.getRDFromJulian(1900, JulianCalendar.JANUARY, 1))/(36525.0);
			double [] coeffs = { 0.003844, 0.083563, 0.865736, 4.867575, 15.845535, 31.332267, 38.2919999, 28.316289, 11.636204, 2.043794};
			deltaT=-9e-6;
			for(int i=1;i<=10;i++){
				deltaT+=coeffs[i-1]*theta;
				theta*=theta;
			}
		}
		else if(year>=1900 && year<=1987){
			double theta = (t.rd-JulianCalendar.getRDFromJulian(1900, JulianCalendar.JANUARY, 1))/(36525.0);
			double [] coeffs = { 2.97e-4, 0.025184, -.181133, 0.553040, -0.861938, 0.677066, -0.212591};
			deltaT=-2e-5;
			for(int i=1;i<=7;i++){
				deltaT+=coeffs[i-1]*theta;
				theta*=theta;
			}
		}
		else{
			double T = (JulianDay.getJDayFromRD(t.rd).getJulianDay()-2382148);
			deltaT=-15+(T/41048480)*T;
		}
		System.out.println(deltaT);
		return deltaT;
	}

	// WHich time? solar or sidereal??
	public static DynamicTime getDynamicFromSolar(Time t){
		double deltaT = getDeltaT(t);
		Time result = Time.addTimes(fromDouble(deltaT/86400),t);
		return new DynamicTime(result.hours, result.minutes, result.seconds, result.rd);
	}
	
	public DynamicTime getSolarFromDynamic(){
		double deltaT = getDeltaT(this);
		Time result = Time.addTimes(this,fromDouble(deltaT/86400));
		return new DynamicTime(result.hours, result.minutes, result.seconds, result.rd);
	}
}
